/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.basics.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rzico.base.BaseMapper;
import com.rzico.base.CommResult;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.Member;
import com.rzico.core.entity.*;
import com.rzico.core.mapper.SysMsgMapper;
import com.rzico.core.plugin.MsgPlugin;
import com.rzico.core.service.*;
import com.rzico.exception.CustomException;
import com.rzico.push.UMengSdk;
import com.rzico.util.CodeGenerator;
import com.rzico.util.MyX509TrustManager;
import com.rzico.util.RedisHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.servlets.DefaultServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <pre>
 * 产品档案业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
@Slf4j
public class MsgService extends BaseServiceImpl<SysMsg, String> {

    @Autowired
    private RedisHandler redisHandler;

    // 获取access_token的接口地址（GET） 限200（次/天） 
    private static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    private static String send_uniform_message = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN";

    private static String send_mp_message = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";

    @Autowired
    private SysMsgMapper sysMsgMapper;

    @Autowired
    private SysPluginService sysPluginService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysTemplateService sysTemplateService;
    @Autowired
    private SysMchService sysMchService;
    @Autowired
    private SysMsgPushService sysMsgPushService;

    @Override
    public BaseMapper<SysMsg, String> getMapper() {
        return sysMsgMapper;
    }

    /**
     * 发起https请求并获取结果
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSON.parseObject(buffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public String getAccessToken(SysPlugin sysPlugin) {
        Object token = null;// redisHandler.get("token.api."+sysPlugin.getAttribute("appid"));
        if (token!=null) {
            return String.valueOf(token);
        }

        String requestUrl = access_token_url.replace("APPID", sysPlugin.getAttribute("appid")).replace("APPSECRET", sysPlugin.getAttribute("appSecret"));
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        if (jsonObject!=null) {

            if (0 != jsonObject.getIntValue("errcode")) {
                throw new CustomException(jsonObject.getString("errmsg"));
            }

            token = jsonObject.getString("access_token");
            if (token!=null) {
                redisHandler.set("token.api." + sysPlugin.getAttribute("appid"),
                        token,
                        Long.valueOf(jsonObject.getIntValue("expires_in")-60)
                );
            }
        }
        return String.valueOf(token);
    }

    /**
     * 模板消息推送
     * @param content 内容
     * @return 模板消息推送
     */
    public void send_uniform_message(SysPlugin sysPlugin,String content) throws IOException {
        try {
            int result = 0;
            log.info(content);
            String token = getAccessToken(sysPlugin);
            String requestUrl = send_uniform_message.replace("ACCESS_TOKEN",token);
            JSONObject jsonObject = httpRequest(requestUrl, "POST", content);
            if (null != jsonObject) {
                if (0 != jsonObject.getIntValue("errcode")) {
                    throw new CustomException(jsonObject.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("发送失败");
        }
    }

    /**
     * 模板消息推送
     * @param content 内容
     * @return 模板消息推送
     */
    public void send_mp_message(SysPlugin sysPlugin,String content) throws IOException {
        try {
            int result = 0;
            log.info(content);
            String token = getAccessToken(sysPlugin);
            String requestUrl = send_mp_message.replace("ACCESS_TOKEN",token);
            JSONObject jsonObject = httpRequest(requestUrl, "POST", content);
            if (null != jsonObject) {
                if (0 != jsonObject.getIntValue("errcode")) {
                    throw new CustomException(jsonObject.getString("errmsg"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("发送失败");
        }
    }

    public void sendNotity(SysUser sysUser,String msgKey,String title,String content,String sound) {
        SysMsgPush sysMsgPush = new SysMsgPush();
        sysMsgPush.setId(CodeGenerator.getUUID());
        sysMsgPush.setIsPush(false);
        sysMsgPush.setMsgLevel(1);
        sysMsgPush.setMsgType(4);
        sysMsgPush.setReadStatus("2");
        sysMsgPush.setPushStatus("0");
        sysMsgPush.setMchId(sysUser.getMchId());
        sysMsgPush.setSendDate(new Date());
        sysMsgPush.setSendUserId("system");
        sysMsgPush.setSendUserName("admin");
        sysMsgPush.setIsAttac("0");

        sysMsgPush.setMsgKey(msgKey);
        sysMsgPush.setMsgContent(content);
        sysMsgPush.setMsgTitle(title);

        if (sysUser!=null) {

            sysMsgPush.setReceiveUserName(sysUser.getUsername());
            sysMsgPush.setReceiveUserId(sysUser.getId());
            sysMsgPushService.insert(sysMsgPush);

            String mchId = sysUser.getMchId();
            if (sysUser.getUserType().equals(1)) {
                SysUser admin = sysUserService.findByUsername("admin");
                mchId = admin.getMchId();
            }

            SysPlugin sysPlugin = sysPluginService.getEnabledPlugin(mchId,SysPlugin.MSGPLUGIN);
            if (sysPlugin!=null) {
                String ticker = "消息通知";
                if (msgKey.equals("msg-order")) {
                    ticker = "订单提醒";
                }
                if (msgKey.equals("msg-shipping")) {
                    ticker = "物流提醒";
                }
                if (msgKey.equals("msg-account")) {
                    ticker = "账单提醒";
                }
                try {
                    UMengSdk androidSdk = new UMengSdk(sysPlugin.getAttribute("umengAndroidAppkey"),sysPlugin.getAttribute("umengAndroidMasterSecret"));
                    androidSdk.sendAndroidCustomizedcast(sysUser.getId(), title, ticker, title, sound);
                    UMengSdk iosSdk = new UMengSdk(sysPlugin.getAttribute("umengIOSAppkey"),sysPlugin.getAttribute("umengIOSMasterSecret"));
                    iosSdk.sendIOSCustomizedcast(sysUser.getId(), title, ticker, title, sound);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            }

        } else {
            throw new CustomException("没有绑定用户");
        }

    }

    public void sendNotity(Member member,String msgKey,String title,String content,String sound) {
        SysUser sysUser = sysUserService.selectByPrimaryKey(member.getUserId());
        if (sysUser!=null) {
            SysMsgPush sysMsgPush = new SysMsgPush();
            sendNotity(sysUser,msgKey,title,content,sound);
        }
    }

    public void sendMPOrderMsg(SysUser sysUser, String first, String keyword1, String keyword2, String keyword3,String keyword4, String remark) {
        log.info("开始发送模板消息");
        //获取消息模块前要先获取用户
        SysMch sysMch = sysMchService.selectByPrimaryKey(sysUser.getMchId());
        if (sysMch==null) {
            throw new CustomException("会员商户不存在");
        }

        SysTemplate template = sysTemplateService.findByTplKey(sysMch.getId(),"mp.order.status");
        if (null == template){
            return;
        }
        log.info("开始发送模板消息1");
        String mpAppId = null;
        String miAppId = null;

        SysUser receiver = sysUser;
        if (receiver==null) {
            throw new CustomException("用户没有激活");
        }
        log.info("开始发送模板消息2");

        String userId = null;
        SysPlugin mpPlugin = sysPluginService.findByPlugin(sysMch.getId(),"weixinOAuth2Plugin");
        if (mpPlugin!=null) {
            mpAppId = mpPlugin.getAttribute("appid");
        } else {
            throw new CustomException("公众号授权插件没有找到");
        }
        log.info("开始发送模板消息3");

//        SysPlugin miPlugin = sysPluginService.findByPlugin(sysMch.getId(),"weixinMiniAuthPlugin");
//        if (miPlugin!=null) {
//            miAppId = miPlugin.getAttribute("appid");
//        }
        if (receiver.getWxId()!=null) {
            userId = receiver.getWxId();
        }
//        if (receiver.getWxmId()!=null) {
//            userId = receiver.getWxmId();
//        }

        if (userId==null) {
            throw new CustomException("没有绑定微信");
        }
        log.info("开始发送模板消息4");

        String data = "";
        data += "{\"touser\":\"" + userId + "\",";
        data += "\"template_id\":\"" + template.getTplId() + "\",";
        data += "\"url\":\"" + "http://"+sysMch.getId()+".rzico.com" + "\",";
        data += "\"topcolor\":\"#FF0000\",";
        data += "\"data\":{";
        data += "\"first\": {\"value\":\"" + first + "\",\"color\":\"#FF0000\"},";
        data += "\"keyword1\": {\"value\":\"" + keyword1 + "\",\"color\":\"#173177\"},";
        data += "\"keyword2\":{\"value\":\"" + keyword2 + "\",\"color\":\"#173177\"},";
        data += "\"keyword3\":{\"value\":\"" + keyword3 + "\",\"color\":\"#173177\"},";
        data += "\"keyword4\":{\"value\":\"" + keyword4+ "\",\"color\":\"#173177\"},";
        data += "\"remark\":{\"value\":\"" + remark + "\",\"color\":\"#173177\"}";
        data += "}";
        data += "}";

        log.debug("开始发送模板消息5");

        try {
            send_mp_message(mpPlugin, data);
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new CustomException(e.getMessage());
        }

    }

    public void sendMiniOrderMsg(SysUser sysUser, String first, String keyword1, String keyword2, String keyword3,String keyword4, String remark) {

        //获取消息模块前要先获取用户
        SysMch sysMch = sysMchService.selectByPrimaryKey(sysUser.getMchId());

        SysTemplate template = sysTemplateService.findByTplKey(sysMch.getId(),"mp.order.status");
        if (null == template){
            return;
        }

        String mpAppId = null;
        String miAppId = null;

        SysUser receiver = sysUser;
        if (receiver==null) {
            throw new CustomException("用户没有激活");
        }

        String userId = null;
        SysPlugin mpPlugin = sysPluginService.findByPlugin(sysMch.getId(),"weixinOAuth2Plugin");
        if (mpPlugin!=null) {
            mpAppId = mpPlugin.getAttribute("appid");
        } else {
            throw new CustomException("公众号授权插件没有找到");
        }

        SysPlugin miPlugin = sysPluginService.findByPlugin(sysMch.getId(),"weixinMiniAuthPlugin");
        if (miPlugin!=null) {
            miAppId = miPlugin.getAttribute("appid");
        }

        if (receiver.getWxmId()!=null) {
            userId = receiver.getWxmId();
        }

        if (userId==null) {
            throw new CustomException("没有绑定微信");
        }

        Map<String,Object> data  = new HashMap<>();
        data.put("touser",userId);
        Map<String,Object> mp_template_msg = new HashMap<>();
        data.put("mp_template_msg",mp_template_msg);
        mp_template_msg.put("appid",mpAppId);
        mp_template_msg.put("template_id",template.getTplId());

        Map<String,Object> miniprogram = new HashMap<>();
        mp_template_msg.put("miniprogram",miniprogram);
        miniprogram.put("appid",miAppId);
        miniprogram.put("path","pages/index/index");

        Map<String,Object> mpdata = new HashMap<>();
        mp_template_msg.put("data",mpdata);
        Map<String,Object> firstMap = new HashMap<>();
        mpdata.put("first",firstMap);
        firstMap.put("value",first);
        firstMap.put("color","#FF0000");

        Map<String,Object> keyword1Map = new HashMap<>();
        mpdata.put("keyword1",keyword1Map);
        keyword1Map.put("value",keyword1);
        keyword1Map.put("color","#173177");

        Map<String,Object> keyword2Map = new HashMap<>();
        mpdata.put("keyword2",keyword2Map);
        keyword2Map.put("value",keyword2);
        keyword2Map.put("color","#173177");

        Map<String,Object> keyword3Map = new HashMap<>();
        mpdata.put("keyword3",keyword3Map);
        keyword3Map.put("value",keyword3);
        keyword3Map.put("color","#173177");


        Map<String,Object> keyword4Map = new HashMap<>();
        mpdata.put("keyword4",keyword4Map);
        keyword4Map.put("value",keyword4);
        keyword4Map.put("color","#173177");

        Map<String,Object> remarkMap = new HashMap<>();
        mpdata.put("remark",remarkMap);
        remarkMap.put("value",remark);
        remarkMap.put("color","#173177");

        try {
            send_uniform_message(miPlugin, JSON.toJSONString(data));
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }

    }

}
